/*
 *	Copyright 2011 andro-inject developers 
 *	Licensed under the Apache License, Version 2.0 (the "License"); 
 *	you may not use this file except in compliance with the License. 
 *	You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 * 
 *	Unless required by applicable law or agreed to in writing, software 
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License. 
 * 
*/

package com.androinject.core.factory.xml;

import java.io.InputStream;

import com.androinject.core.factory.ComponentProcessor;
import com.androinject.core.factory.DefaultComponentFactoryInitializationHelper;
import com.androinject.core.factory.input.FileInputSource;
import com.androinject.core.factory.input.InputSource;
import com.androinject.core.factory.input.InputStreamInputSource;

/**
 * DefaultXmlComponentFactory is the default implementation of the ComponentFactory
 * interface using a xml component configuration.
 */
public class DefaultXmlComponentFactory extends XmlComponentFactory {
	
	
	protected InputSource inputSource;
	

	protected DefaultXmlComponentFactory() {
		
	}
	
	
	/**
	 * Creates a new DefaultXmlComponentFactory instance. Takes the path to the xml component configuration 
	 * as parameter. Identical to calling DefaultXmlComponentFactory(file, null).
	 * @param file path to the xml component configuration
	 */
	public DefaultXmlComponentFactory(String file) {
		this(file, null);
	}
	
	
	/**
	 * Creates a new DefaultXmlComponentFactory instance. Takes the path to the xml component configuration 
	 * and an array of custom component processors as parameters.
	 * @param file path to the xml component configuration
	 * @param componentProcessors array of custom component processors that should be added to the factory
	 */
	public DefaultXmlComponentFactory(String file, ComponentProcessor[] componentProcessors) {
		this(new FileInputSource(file), componentProcessors);
	}

	
	/**
	 * Creates a new DefaultXmlComponentFactory instance. Takes an InputStream as parameter that is used
	 * to read the xml component configuration. Identical to calling DefaultXmlComponentFactory(inputStream, null)
	 * @param inputStream InputStream that is used to read the component configuration
	 */
	public DefaultXmlComponentFactory(InputStream inputStream) {
		this(inputStream, null);
	}
	
	
	/**
	 * Creates a new DefaultXmlComponentFactory instance. Takes an InputStream and an array of custom
	 * component processors as parameter. The xml component configuration is read from the InputStream.
	 * @param inputStream InputStream that is used to read the component configuration
	 * @param componentProcessors An array of custom component processors that should be added to the factory
	 */
	public DefaultXmlComponentFactory(InputStream inputStream, ComponentProcessor[] componentProcessors) {
		this(new InputStreamInputSource(inputStream), componentProcessors);
	}
	
	
	/**
	 * Creates a new DefaultXmlComponentFactory instance. An InputSource that provides access to the 
	 * xml component configuration can be passed. Identical to calling DefaultXmlComponentFactory(inputSource, null).
	 * @param inputSource InputSource that provides access to the xml component configuration
	 */
	public DefaultXmlComponentFactory(InputSource inputSource) {
		this(inputSource, null);
	}
	
	
	/**
	 * Creates a new DefaultXmlComponentFactory instance. Takes an InputSource an a list of custom component processors
	 * as parameter. The component configuration is read from the InputSource.
	 * @param inputSource InputSource that provides access to the xml component configuration
	 * @param componentProcessors An array of custom component processors that should be added to the factory
	 */
	public DefaultXmlComponentFactory(InputSource inputSource, ComponentProcessor[] componentProcessors) {
		this.inputSource = inputSource;
		this.setupComponentProcessors(componentProcessors);
		this.loadComponents();
	}
	
	
	protected void setupComponentProcessors(ComponentProcessor[] componentProcessors) {
		DefaultComponentFactoryInitializationHelper.setupDefaultComponentProcessors(this);
		if (componentProcessors != null) {
			for (ComponentProcessor processor : componentProcessors) {
				this.addComponentProcessor(processor);
			}
		}
	}
	
	
	@Override
	protected InputSource getInputSource() {
		return this.inputSource;
	}
	
}
